//=============================================================================
// tfConSpawnFire.
//=============================================================================
class tfConSpawnFire extends TFProjectileFire
	placeable;

var class<BaseSentinel> sentClasses[6];
var class<tfStation> BuildType[10];
var() float MaxSpawnHeight;
var() sound DeploySound, FailSound;

function DoFireEffect()
{
    local Vector StartProj, StartTrace, X,Y,Z;
    local Rotator Aim;
    local Vector HitLocation, HitNormal;
    local Actor Other;
	local tfStation sgb;
	local tfpri pri;
	local tfgri gri;
	local float Amount, hf;
//	local sentinelplayerreplicationinfo spri;

    if(instigator == None)
           return;
    Instigator.MakeNoise(1.0);
    Weapon.GetViewAxes(X,Y,Z);

    pri=tfpri(instigator.PlayerReplicationInfo);
    gri=tfgri(weapon.level.Game.GameReplicationInfo);


    StartTrace = Instigator.Location + Instigator.EyePosition();
    StartProj = StartTrace + X*ProjSpawnOffset.X + Y*ProjSpawnOffset.Y;

	Aim = AdjustAim(StartProj, AimError);

    Other = Trace(HitLocation, HitNormal, StartProj, StartTrace, true);
    if(ShieldSphere(other)!=None)
        other=(shieldsphere(other)).Shield.Sentinel;
    if(ShieldMesh(other)!=none && ShieldMesh(other).Base!=none && ShieldSentinel(ShieldMesh(other).Base)!=none)
            other=ShieldMesh(other).Base;
    if(Other!=None)
    {
        if(vsize(starttrace-hitlocation)<=64)
            StartProj = HitLocation-vector(aim)*5;
        else StartProj = StartTrace + X*ProjSpawnOffset.X/4 + Y*ProjSpawnOffset.Y;

        if(tfStation(other)!=none && pri.BuildMode==0)
            aim=rotator(normal(starttrace-other.Location));
    }
    else StartProj = StartTrace + X*ProjSpawnOffset.X/4 + Y*ProjSpawnOffset.Y;

    if(pri.buildmode<7 && pri.RES>=gri.buildcost[pri.buildmode])
    {
        if(tfconstructor(weapon).CheckDist(pri.BuildMode, StartProj) && tfconstructor(weapon).CheckArea(pri.BuildMode, StartProj) && tfconstructor(weapon).CheckTerr(pri.BuildMode, StartProj) && tfconstructor(weapon).CheckControl(gri.buildcost[pri.buildmode], pri.team.teamindex, gri))
        {
            sgb=spawn(buildtype[pri.buildmode],instigator,,startproj,aim);
	        if(sgb!=none)
            {
                sgb.setInitialTeam(instigator.playerreplicationinfo.Team.TeamIndex);
	            Instigator.PlaySound(Sound'TFMedia.tfPlaceBuilding',SLOT_Interact,TransientSoundVolume*1.5);
	            pri.SubRES(-gri.buildcost[pri.buildmode]);
                return;
            }
        }
    }
    else if(pri.buildmode==10 && pri.res>=50)
    {
        if(spawn(class'Taskforces.TFECSphere',,,startproj,aim)!=none)
        {
            pri.SubRES(-50);
            Instigator.PlaySound(Sound'TFMedia.tfDropEC',SLOT_Interact,TransientSoundVolume);
            return;
        }
    }
	else if(tfBaseCore(other)==none && tfStation(other)!=none && tfStation(other).myteam==pri.Team.teamindex)
	{
	    if(pri.buildmode==7 && tfbasecore(other)==none && tfstation(other).grade>0)
        {
            hf=(tfstation(other).maxhealth/(gri.buildcost[tfstation(other).nameindex-1]*tfstation(other).grade))*2.00;
            amount=fmin(tfstation(other).maxhealth-tfstation(other).health,pri.res*hf);

            pri.SubRES(-(amount/hf));
            tfStation(other).health+=amount;

            if(amount>0)
            {
                Instigator.PlaySound(Sound'TFMedia.tfStationRepair',SLOT_Interact,TransientSoundVolume);
                other.spawn(class'Taskforces.tfShieldHealFX');
                other.spawn(class'Taskforces.tfShieldHealFX');
                return;
            }
        }
        else if(pri.buildmode==8)
        {
            if(tfStation(other)!=none)
            {
                //if(tfstation(other).grade>0) pri.AddRES((gri.buildcost[tfstation(other).nameindex-1]*tfstation(other).grade) /3);
                //else pri.AddRES(gri.buildcost[tfstation(other).nameindex-1]/2);
                tfStation(other).destructed(instigator, true);
                return;
            }
        }
        else if(pri.buildmode==9 && tfstation(other).grade>0)
        {
            if(pri.RES>=gri.buildcost[tfStation(other).nameindex-1] && tfStation(other).grade<3 && tfconstructor(weapon).CheckControl(gri.buildcost[tfStation(other).nameindex-1], pri.team.teamindex, gri))
            {
                pri.SubRES(-gri.buildcost[tfStation(other).nameindex-1]);
                tfStation(other).upgrade(instigator);
                return;
            }
        }
    }
    //Sentinel Interaction
    else if(baseSentinel(other)!=none && baseSentinel(other).PlayerReplicationInfo.Team.TeamIndex==instigator.PlayerReplicationInfo.Team.teamindex)
    {
         if(pri.buildmode==7)
         {
         	if(baseSentinel(other).Health >= baseSentinel(other).HealthMax)
                return;

            hf=(baseSentinel(other).HealthMax/400)*2.00;
            amount=fmin(baseSentinel(other).HealthMax-baseSentinel(other).health,pri.res*hf);

            pri.SubRES(-(amount/hf));
            baseSentinel(other).health+=amount;

            if(amount>0)
            {
                Instigator.PlaySound(Sound'TFMedia.tfStationRepair',SLOT_Interact,TransientSoundVolume);
                Other.spawn(class'Taskforces.tfShieldHealFX');
                Other.spawn(class'Taskforces.tfShieldHealFX');
                return;
            }
         }
         if(pri.buildmode==8)
         {
          tfconstructor(weapon).DoRemove(baseSentinel(other),instigator.Controller);
          return;
         }
    }
    else if((pri.BuildMode==11 || pri.BuildMode==12 || pri.BuildMode==13) && tfconstructor(weapon).CheckArea(pri.BuildMode, StartProj) && tfconstructor(weapon).CheckTerr(pri.BuildMode, StartProj))
    {
        Deploy(pri.BuildMode-10);

        return;
    }
    //Playercontroller(instigator.controller).ReceiveLocalizedMessage(class'TaskForces.tfBuildFailMsg');
    Instigator.PlaySound(sound'TFMedia.tfGUIFail',SLOT_None,TransientSoundVolume);
}

//START SENTINEL
function bool Deploy(int num)
{
	local Vector X, Y, Z;

	Weapon.GetViewAxes(X, Y, Z);
	if(rotator(X).Pitch > 1024)
	{
		if(!DeployCeiling(X,num))
			return false;
	}
	else
	{
		if(!DeployFloor(X,num))
			return false;
	}

	return true;
}

function bool DeployFloor(vector X, int num)
{
	local Vector DeployLocation;
	local BaseSentinel PlacedSentinel;
	local tfpri pri;
	local int myteam;
	local class<BaseSentinel> cl;

	pri=tfpri(instigator.PlayerReplicationInfo);
	myteam=pri.Team.TeamIndex;
	if(!CanDeploy(num))
		return false;
	DeployLocation = Instigator.Location + X * 100;

	if(!Weapon.FastTrace(DeployLocation, Instigator.Location))
	{
		Instigator.ReceiveLocalizedMessage(class'DeployerMessage', 3);
		return false;
	}
	cl=sentClasses[(num-1)*2];
	if(cl!=none)
    	PlacedSentinel = Spawn(cl,,, DeployLocation, rot(0, 0, 0));
    else
        return false;
/*    if(num==1 && pri.RES>=FloorSentinelClass.default.cost)
	   PlacedSentinel = Spawn(FloorSentinelClass,,, DeployLocation, rot(0, 0, 0));
	else if(num==2 && pri.RES>=FloorTeleSentinelClass.default.cost)
	   PlacedSentinel = Spawn(FloorTeleSentinelClass,,, DeployLocation, rot(0, 0, 0));
	else if(num==3 && pri.RES>=ShieldSentinelClass.default.cost)
	   PlacedSentinel = Spawn(ShieldSentinelClass,,, DeployLocation, rot(0, 0, 0));
	else
	   return false;*/

	if(PlacedSentinel != None)
	{
		PlacedSentinel.InitializeFor(Instigator);

		//Just in case Sentinel destroyed itself on initialization...
		if(PlacedSentinel == None)
			return false;

		Weapon.PlaySound(DeploySound, SLOT_Interact, TransientSoundVolume,,,, false);
		pri.SubRES(-PlacedSentinel.cost);
		tfgri(level.game.gamereplicationinfo).control[myteam]+=PlacedSentinel.cost;

		return true;
	}

	return false;
}

function bool DeployCeiling(vector X, int num)
{
	local Vector DeployLocation, HitLocation, HitNormal;
	local Actor Other;
	local BaseSentinel PlacedSentinel;
	local tfpri pri;
	local int myteam;
	local class<BaseSentinel> cl;

	pri=tfpri(instigator.PlayerReplicationInfo);
	myteam=pri.Team.TeamIndex;

	if(Instigator.IsHumanControlled())
		Other = Weapon.Trace(HitLocation, HitNormal, Instigator.Location + (X * MaxSpawnHeight), Instigator.Location + (X * 64), true, vect(16, 16, 16));
	else
		Other = Weapon.Trace(HitLocation, HitNormal, Instigator.Location + vect(0, 0, 400), Instigator.Location + vect(0, 0, 64), true, vect(16, 16, 16));

	if(Other == None)
	{
		Instigator.ReceiveLocalizedMessage(class'DeployerMessage', 4);
		return false;
	}

	if(!CanDeploy(num))
		return false;

	if(!Other.bWorldGeometry)
	{
		Instigator.ReceiveLocalizedMessage(class'DeployerMessage', 3);
		return false;
	}

	if(!Weapon.FastTrace(HitLocation - vect(0, 0, 150), HitLocation))
	{
		Instigator.ReceiveLocalizedMessage(class'DeployerMessage', 3);
		return false;
	}

	if(Acos(HitNormal dot vect(0, 0, -1)) > 3.14159265359 / 4)
	{
		Instigator.ReceiveLocalizedMessage(class'DeployerMessage', 5);
		return false;
	}

	DeployLocation = HitLocation - vect(0, 0, 10);
	cl=sentClasses[(num-1)*2+1];
	if(cl!=none)
    	PlacedSentinel = Spawn(cl,,, DeployLocation, rot(0, 0, 0));
    else
        return false;
/*	if(num==1 && pri.RES>=CeilingSentinelClass.default.cost)
	   PlacedSentinel = Spawn(CeilingSentinelClass,,, DeployLocation, rot(0, 0, 0));
	else if(num==2 && pri.RES>=CeilingTeleSentinelClass.default.cost)
	   PlacedSentinel = Spawn(CeilingTeleSentinelClass,,, DeployLocation, rot(0, 0, 0));
	else
	   return false;*/

	if(PlacedSentinel != None)
	{
		PlacedSentinel.SetBase(Other);
		PlacedSentinel.InitializeFor(Instigator);
		Weapon.PlaySound(DeploySound, SLOT_Interact, TransientSoundVolume,,,, false);

		pri.SubRES(-PlacedSentinel.cost);
		tfgri(level.game.gamereplicationinfo).control[myteam]+=PlacedSentinel.cost;
		return true;
	}

	return false;
}

function bool CanDeploy(int num)
{
	local Controller C;
	local int CannonCount;
	local tfpri pri;
	local int myteam;
	local tfgri gri;

    if(instigator == None)
           return false;
	pri=tfpri(instigator.PlayerReplicationInfo);
	gri=tfgri(weapon.level.Game.GameReplicationInfo);
    myteam=pri.Team.TeamIndex;

	if(Instigator == None)
		return false;

	for(C = Level.ControllerList; C != None; C = C.nextController)
	{
		if(C.IsA('BaseSentinelController') && BaseSentinelController(C).sent.InstigatorController == Instigator.Controller)
			CannonCount++;
	}

    if(tfgame(level.game).MaxSentinel != 0)
    {
             if(CannonCount >= tfgame(level.game).MaxSentinel)
	         {
             Instigator.ReceiveLocalizedMessage(class'DeployerMessage', 1);
             return false;
             }
	}

	if(pri.res < sentClasses[(num-1)*2].default.cost)
	{
		Instigator.ReceiveLocalizedMessage(class'DeployerMessage', 2);
		return false;
	}
	if(tfconstructor(weapon).CheckControl(sentClasses[(num-1)*2].default.cost,myteam,gri)==false)
	{
        Instigator.ReceiveLocalizedMessage(class'DeployerMessage', 0);
        return false;
    }

	return true;
}
//END SENTINEL

defaultproperties
{
     sentClasses[0]=class'taskforces.FloorSentinel'
     sentClasses[1]=class'taskforces.CeilingSentinel'
     sentClasses[2]=class'taskforces.FloorTelemetrySentinel'
     sentClasses[3]=class'taskforces.CeilingTelemetrySentinel'
     sentClasses[4]=class'taskforces.ShieldSentinel'
     sentClasses[5]=none
     BuildType(0)=Class'taskforces.tfShield'
     BuildType(1)=Class'taskforces.tfGuardian'
     BuildType(2)=Class'taskforces.tfPortal'
     BuildType(3)=Class'taskforces.tfArmory'
     BuildType(4)=Class'taskforces.tfGenerator'
     BuildType(5)=Class'taskforces.tfOutpost'
     BuildType(6)=class'taskforces.tfMedivac'
     BuildType(7)=class'taskforces.TFWarhead'
     MaxSpawnHeight=300.000000
     DeploySound=Sound'WeaponSounds.BaseGunTech.BReload2'
     ProjSpawnOffset=(X=240.000000,Y=8.000000)
     bLeadTarget=False
     bWaitForRelease=True
     bModeExclusive=False
     TransientSoundVolume=0.750000
     AmmoClass=Class'taskforces.TFConAmmo'
}
